<template>
  <a-radio-group
    placeholder="请选择"
    :value="state.selectValue"
    allow-clear
    @change="onChange"
    v-bind="$attrs"
  >
    <slot :options="state.optionDatas" v-if="allowCancel">
      <a-radio
        :key="index"
        :value="item[labelValue]"
        :item="item"
        :disabled="item.disabled || disabledValues.includes(item[labelValue])"
        @click.stop.prevent="e => toggleRadio(e, item)"
        v-for="(item, index) in state.optionDatas"
      >
        {{ item[label] }}
      </a-radio>
    </slot>
    <slot :options="state.optionDatas" v-else>
      <a-radio
        :key="index"
        :value="item[labelValue]"
        :item="item"
        :disabled="item.disabled || disabledValues.includes(item[labelValue])"
        v-for="(item, index) in state.optionDatas"
      >
        {{ item[label] }}
      </a-radio>
    </slot>
  </a-radio-group>
</template>
<script setup>
import { post, get } from 'server/axios'
import { evalPropChain } from 'utils/utils'
import { reactive, watch } from 'vue'
const props = defineProps({
  value: {
    type: [String, Number, Array],
    default: undefined
  },
  disabledValues: {
    type: Array,
    default: () => {
      return []
    }
  },
  // 是否允许单选框反选
  allowCancel: {
    type: Boolean,
    default: false
  },
  url: {
    type: String,
    default: ''
  },
  // 下拉框显示的文本字段
  label: {
    type: String,
    default: 'label'
  },
  // 下拉框值的字段
  labelValue: {
    type: String,
    default: 'value'
  },
  // 请求接口参数
  params: {
    type: Object,
    default: () => {
      return {}
    }
  },
  // 支持自定义传options
  options: {
    type: Array,
    default: () => []
  },
  method: {
    type: String,
    default: 'post'
  },
  respField: {
    type: String,
    default: 'data'
  },
  immediate: {
    type: Boolean,
    default: false
  }
})
const AXIOS_METHOD = {
  get: get,
  post: post
}
const state = reactive({
  selectValue: props.value,
  reqParams: props.params,
  optionDatas: props.options || []
})
const emit = defineEmits(['input', 'update:options', 'change', 'update:value'])

const getRquerstURL = () => {
  return props.url.startsWith('http')
    ? props.url
    : `${process.env.VUE_APP_CONFIG}/${props.url}`
}
const queryServiceData = async () => {
  const serverURL = getRquerstURL()
  const resp = await AXIOS_METHOD[props.method.toLowerCase()](
    serverURL,
    state.reqParams
  )
  const isNumber = val => {
    return parseFloat(val) !== 'NaN'
  }
  const data = evalPropChain(resp, props.respField)
  if (Object.prototype.toString.call(data) === '[object Object]') {
    state.optionDatas = Object.keys(data).map(key => {
      return {
        label: data[key],
        value: isNumber(key) ? parseInt(key) : key
      }
    })
  } else {
    state.optionDatas = data
  }

  emit('update:options', state.optionDatas)
}
watch(
  () => props.params,
  (newV, v) => {
    if (JSON.stringify(newV) !== JSON.stringify(v)) {
      if (props.url) {
        state.reqParams = props.params
        queryServiceData()
      }
    }
  }
)
watch(
  () => props.value,
  val => {
    state.selectValue = val
  }
)
watch(
  () => state.selectValue,
  val => {
    emit('update:value', val)
  }
)
watch(
  () => props.immediate,
  () => {
    if (props.url && props.immediate) {
      queryServiceData()
    }
  },
  { immediate: true }
)
const toggleRadio = (e, item) => {
  const value = item[props.labelValue]
  const disabled = item.disabled || props.disabledValues.includes(value)

  if (props.allowCancel && !disabled) {
    if (state.selectValue === value) {
      // 再次点击同一个选项,取消选中
      state.selectValue = undefined
    } else {
      // 选中新的选项
      state.selectValue = value
    }
    emit('change', e)
  }
}
const onChange = e => {
  if (!props.allowCancel) {
    emit('update:value', e.target.value)
    emit('change', e)
  }
}
</script>
